package br.ufc.custom.Graph;

import java.util.Collections;
import java.util.List;
import java.util.Vector;

import br.ufc.custom.multiHistogram.Cell;
import br.ufc.custom.multiHistogram.MultiHistogram;
import br.ufc.util.NDimensionalArray;

public class Graph {
	
	private List<Vertex> vertices;
	private int edgesSize;
	
	public Graph(MultiHistogram mh){
		this.verticesSize = 0;
		this.edgesSize = 0;
		vertices = new Vector<Vertex>();
		NDimensionalArray narray = mh.getNarray();
		List<Cell> cells = mh.getCells();
		int[] dimensionsSize = mh.getDimensionsSize();
		int dimensionsAmount = mh.getDimensionsAmount();
		
		creteVertices(narray, dimensionsSize, dimensionsAmount);		
		Collections.sort(vertices);
		createEdges(narray, cells, dimensionsSize, dimensionsAmount);
	}
	
	private int verticesSize;
	public List<Vertex> getVertices() {
		return vertices;
	}

	private void createEdges(NDimensionalArray narray,
			List<Cell> cells,
			int[] dimensionsSize,
			int dimensionsAmount) {
		
		for(int i = 0; i < cells.size(); i++){
			Vertex v = vertices.get(i);
			Cell c = cells.get(i);
			for (Cell cellNeighboor : c.getEdges().keySet()) {
				Vertex neighbor = vertices.get(cellNeighboor.getID());
				v.addNeighbor(neighbor, c.getEdges().get(cellNeighboor));
				this.edgesSize ++;
			}
			System.out.println("vertex: " + i + " " +v.getNeighbors().size());
		}		
		this.edgesSize = this.edgesSize / 2;
	}

	private void creteVertices(NDimensionalArray narray, int[] dimensionsSize, int dimensionsAmount) {
		int iterator[] = new int[dimensionsAmount];
		for(int i = 0; i < dimensionsAmount; i++){
			iterator[i] = 0;
		}		

		boolean iterate = true;
		Cell cell = null;
		while(iterate){
			cell = (Cell)narray.get(iterator);
			vertices.add(new Vertex(cell.getID(), cell.getCount(), cell));

			for(int i = 0; i < dimensionsAmount; i ++){
				iterator[i] ++;			
				if(iterator[i] == dimensionsSize[i]){
					if(i == dimensionsAmount - 1){
						iterate = false;
						break;
					}
					iterator[i] = 0;					
				}
				else{
					break;
				}
			}
		}
		this.verticesSize = vertices.size();
	}
	
	public void print(){
		System.out.println("Graph");
		for(int i = 0;  i < vertices.size(); i++){
			Vertex v = vertices.get(i);
			System.out.println("Vertex: " + v.getID() + " " + i);
			System.out.print("Neighbors: ");
			for(Vertex n : v.getNeighbors().keySet()){
				System.out.print(n.getID() + ":" + v.getNeighbors().get(n) + " ");
			}
			System.out.println("");
		}		
	}
	
	public void printIterator(int[] iterator){
		System.out.println("");
		for(int i : iterator){
			System.out.print(i + " ");
		}
		System.out.println("");
	}
	public int getVerticesSize() {
		return verticesSize;
	}

	public int getEdgesSize() {
		return edgesSize;
	}

}
